Step 4 - Create the interaction handler for selecting a widget

In this tutorial you create an application in which users can scroll the list of widgets contained in the Widget Grid List Box and enable them to select from that list a widget represented by a Widget Item Prefab. The Grid List Box 3D node provides the horizontal scrolling you can set in the Kanzi Studio project, but you need to define the application logic that handles the widget selection.

In this step of the tutorial you implement the functionality that handles the selection of the widget item when the user clicks a widget:

To create the interaction handler for selecting a widget:

  1. In the onProjectLoaded function after storing the acquired resources and nodes (after the line swap(m_widgetDescriptionTextBlock, widgetDescriptionTextBlock);) get the initial position of the animation target node. You later use the position to calculate the final keyframes of the animation that moves the camera node to the widget selected in the Widget Grid List Box.
    virtual void onProjectLoaded() KZ_OVERRIDE
    {
    ...
    	// Get the initial position of the animation target node.
    	// The full transformation consists of this translation and the translation of the target object.
    	m_cameraTransformationTarget = m_animationTargetNode->getLayoutTransformation();
    ...
    }
  2. In the ProgrammerTutorialApplication class after the onProjectLoaded function implement the event handler for selecting the widgets in the Widget Grid List Box. Use the index of the selected widget to retrieve the selected widget from the Widget Grid List Box node.
    class ProgrammerTutorialApplication : public ExampleApplication
    {
    ...
    // Handler for the selection message when user selects a widget
    // in the Widget Grid List Box node.
    void onWidgetListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
    {
    	// Retrieve index of selected list box item from the message arguments.
    	optional<size_t> selectedItemIndex = messageArguments.getSelectedItemIndex();
    
    	if (selectedItemIndex)
    	{
    		// Retrieve the selected list box item by its index.
    		m_selectedWidgetListBoxItem = m_widgetListBox->getItem(*selectedItemIndex);
    
    	}
    ...
    }
  3. A target animation repositions the camera. The animation takes the current transformation of the node and animates to another transformation defined by another node.
    Animation target node for the Camera node defined in the Kanzi Studio project and its transformation are stored in the member variables m_animationTargetNode, m_camera, and m_cameraTransformationTarget. Now the stored camera transformation is updated with the translation of the selected widget.
    void onWidgetListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
    {
    ...
    	if (selectedItemIndex)
    	{
    	...
    		// Calculate a new value for the camera animation target node.
    		{
    			// Get the current transformation.
    			Matrix4x4 selectedItemTransformation = m_selectedWidgetListBoxItem->getFinalTransformation();
    			// Get the camera's relative transformation target position.
    			Matrix4x4 transformationTarget = m_cameraTransformationTarget;
    
    			// Add the position of the object of interest to the target camera transformation.
    			transformationTarget.setTranslation(transformationTarget.getTranslation() +
    				selectedItemTransformation.getTranslation());
    
    			// The final position of the currently selected widget differs depending on its position
    			// in the Widget Grid List Box node.
    			// This is why the final keyframes in all translation animation data items in the
    			// Camera Target Animation are set to the Widget Item Animation Target node and determined
    			// during the runtime. See Keyframe output values.
    			m_animationTargetNode->setLayoutTransformation(transformationTarget);
    		}
    	}
    ...
    }
  4. Now that the transformation target node of the Camera node target animation is updated, you can initiate the target animation for the Camera node and the highlight animation for the selected widget. The highlight animation rotates the widget around its x axis from fixed values 0 to 60 degrees and is defined in the Kanzi Studio project.
    The second parameter in the addAnimationItem function call defines whether the animation is played in reverse, and the third parameter how many times the animation is played.
    void onWidgetListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
    {
    ...
    	if (selectedItemIndex)
    	{
    	...
    		// Start the animation for the Camera node.
    		m_camera->addAnimationItem(m_targetAnimationClip, false, 1);
    		// Start the animation for the widget highlighting.
    		m_selectedWidgetListBoxItem->addAnimationItem(m_highlightAnimationClip, false, 1);
    	...
    	}
    ...
    }
  5. Get the widget description from the WidgetDescription property, and set the value of the Text property of the Text Block 2D node to the value of the WidgetDescription property, and make visible the Widget Description Layer that contains the panel on the right side of the application window.
    void onWidgetListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
    {
    ...
    	if (selectedItemIndex)
    	{
    	...
    		{
    			// Set the widget description to the description text.
    			// The description text is taken from the widget node.
    			string widgetDescription = m_selectedWidgetListBoxItem->getProperty(*m_widgetDescriptionPropertyType);
    			m_widgetDescriptionTextBlock->setText(widgetDescription);
    
    			// Make the Widget Description Layer node visible.
    			m_widgetDescriptionNode->setVisible(true);
    		}
    	...
    	}
    ...
    }
  6. In the onProjectLoaded function register the message handler for the ItemSelectedMessage of the Widget Grid List Box node before storing the acquired resources and nodes (before the line using std::swap;) .
    virtual void onProjectLoaded() KZ_OVERRIDE
    {
    ...
    // Add a message handler for selecting the Grid List Box 3D item events.
    widgetListBox->addMessageHandler(GridListBox3D::ItemSelectedMessage,
    	bind(&ProgrammerTutorialApplication::onWidgetListBoxItemSelected, this, placeholders::_1));		
    ...
    }
    When you click a widget, the application highlights the widget using the two animations you specified, makes the Widget Description Layer node visible and shows the widget description in the Widget Description Layer.

See also

Editing animation clips

Creating keyframe animations

Animations

< PREVIOUS STEP

NEXT STEP >